package com.alisls.shequtao.service.user.service.impl;

import com.alisls.shequtao.service.user.dao.UserDAO;
import com.alisls.shequtao.service.user.dto.UserDTO;
import com.alisls.shequtao.service.user.dto.UserPwdDTO;
import com.alisls.shequtao.service.user.entity.UserDO;
import com.alisls.shequtao.service.user.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;

/**
 * 用户Service实现
 *
 * @author Ke Wang
 */
@Service("userService")
@AllArgsConstructor
@Log4j2
public class UserServiceImpl extends ServiceImpl<UserDAO, UserDO> implements UserService {

    private final UserDAO userDAO;

    /**
     * 根据用户标识查询用户
     * 注解@Cacheable声明方法是可缓存的(value = "缓存的名字", key = "缓存Key")
     * @param id 用户ID
     * @return 用户DTO
     */
    @Cacheable(cacheNames = "sys_user", key = "#id")
    @Override
    public UserDTO getUser(Long id) {
        UserDO userDO = this.getById(id);

        UserDTO userDTO = new UserDTO();
        if (userDO != null) {
            BeanUtils.copyProperties(userDO, userDTO);
        }

        return userDTO;
    }

    /**
     * 根据用户名查询用户
     */
    @Override
    public UserDTO getUser(String username) {
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        UserDO userDO = userDAO.selectOne(queryWrapper);

        UserDTO userDTO = new UserDTO();
        if (userDO != null) {
            BeanUtils.copyProperties(userDO, userDTO);
        }

        return userDTO;
    }

    /**
     * 根据用户名查询用户（用户带有密码信息）
     */
    @Override
    public UserDTO getUserWithPwd(String username) {
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        UserDO userDO = userDAO.selectOne(queryWrapper);

        UserDTO userDTO = new UserPwdDTO();
        if (userDO != null) {
            BeanUtils.copyProperties(userDO, userDTO);
        }

        return userDTO;
    }

    /**
     * 获取用户菜单权限
     * 1.用户本身的菜单权限
     * 2.用户所有角色对应的菜单权限
     * 3.用户所有角色对应权限组内的菜单权限
     * 4.用户所在用户组对应的菜单权限
     * @param username 用户名
     * @return 用户的菜单权限
     */
    @Override
    @PreAuthorize("hasAuthority('user:getUserMenuPermissions')")
    public UserDTO getUserMenuPermissions(String username) {
        return null;
    }

    /**
     * 保存用户
     * 注意：Jpa在保存用户前，会根据ID查询用户，之后再保存
     */
    @Override
    @CachePut(cacheNames = "sys_user", key = "#userDTO.id")
    public UserDTO save(UserDTO userDTO) {
        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(userDTO, userDO);

        this.save(userDO);
        userDTO.setId(userDO.getId());

        return userDTO;
    }

    /**
     * 修改用户
     */
    @Override
    @CachePut(cacheNames = "sys_user", key = "#userDTO.id")
    public UserDTO update(UserDTO userDTO) {
        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(userDTO, userDO);

        this.save(userDO);
        if (log.isDebugEnabled()) {
            log.debug("用户信息修改成功，新的用户数据为{}", userDO);
        }
        return userDTO;
    }

}
